package com.doyutu.seed.common.handler;

import com.doyutu.seed.common.exception.BadCheckException;
import com.doyutu.seed.common.exception.BasicException;
import com.doyutu.seed.entity.result.Result;
import com.google.common.base.Throwables;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @author DoyuTu
 * @version 0.0.1
 * spring-boot-project-seed
 */
@ControllerAdvice(basePackages = {"com.doyutu.seed.controller"})
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public Object baseExceptionHandler(Exception ex) {
        //空指针异常
        if (ex instanceof NullPointerException) {
            log.error("傻吊又抛空指针->{}", Throwables.getStackTraceAsString(ex));
            return Result.fail();
        }
        //@Valid异常捕获
        if (ex instanceof BindException) {
            BindException exception = (BindException) ex;
            return Result.fail(getReduceStr(exception));
        }
        //参数校验异常
        if (ex instanceof BadCheckException) {
            BadCheckException e = (BadCheckException) ex;
            return Result.fail(e.getFieldName() + ": 错误的值 " + e.getFieldValue());
        }
        //业务逻辑异常
        if (ex instanceof BasicException) {
            BasicException e = (BasicException) ex;
            return new ResponseEntity<>(Result.fail(e.getMessage()), HttpStatus.OK);
        }
        //未捕获的异常
        log.error("ErrorCause->{}", Throwables.getStackTraceAsString(ex));
        return Result.fail();
    }

    private String getReduceStr(BindException exception) {
        return exception.getFieldErrors().stream()
                .map(e -> e.getField() + ":" + e.getDefaultMessage())
                .collect(Collectors.joining("\n"));
//                .reduce("", (s1, s2) -> s1 + "\n" + s2);
    }

}
